# -*- coding: utf-8 -*-
"""
Created on Tue Oct  8 18:20:10 2019

@author: minuks3, mckeanb
"""

import numpy as np
import perform_sim
import convertSvals
import socket
import datetime
import monitor_client
import time
import database_comm as database
import mysql.connector
from mysql.connector import Error

sub_thicks = {
    "Rogers RO3003" : 1.52,
    "Rogers RO3010" : 1.28
}

ENABLE_MONITOR = False
    
def runSim(length, width, trace, delta_s, sub_material):
    try:
        # Check to see if this sim has already been performed
        if(database.simulationExists(trace, length, width, delta_s, sub_material)):
            print("Simulation skipped, results already exist for trace = "+trace+" and width = "+str(width)+"mm.")
            return

        # Print simulation values
        #print("Simulation Starting")
        print("INPUTS")
        print("  Trace Position: "+trace)
        print("   Dogbone Width: "+str(width)+"mm")
        print("   Dogbone Length: "+str(length)+"mm")

        print("OUTPUTS")

        startTime = time.time()

        # Run the simulation and retrive a 2x2 S matrix
        result = perform_sim.runsim(trace,width,length,delta_s,sub_material,sub_thicks[sub_material])
        
        runtime = time.time() - startTime
        
        # If the simulation performed properly
        if(len(result)>0):
        
            # Print S Matrix
            print("  S Matrix:")
            print(result[0]["sMat"])
            
            # Convert the S matrix from the simulation into an impedance
            z_im = convertSvals.convert_svals(result[0]["sMat"], trace, sub_material)  # Convert S mat to im(Z)
            print("     im(z): "+str(z_im)+"j")
            
            # Upload results to database
            database.uploadResults(width, length, z_im, trace, result[0]["converged"],
                            result[0]["delta_s"], runtime, sub_material)
                
            if ENABLE_MONITOR:
                monitor_client.send_confirmation(monitorServer, width, trace, z_im)    # Inform monitor server
        result=[]
        
        
    except Error as e:
        print("Error communicating with the MySQL server:", e)
    if ENABLE_MONITOR:
        monitor_client.send_stop_signal(monitorServer)
                
            #print()
                
def runSims(startWidth, stopWidth, length, trace, delta_s, sub_material):
    
    minInterval = 0.2
    
    runSim(length, startWidth, trace, delta_s, sub_material)
    runSim(length, stopWidth, trace, delta_s, sub_material)
    
    stateQueue = []
    stateQueue.append({"start":startWidth,"end":stopWidth})
    while(len(stateQueue) > 0):
        state = stateQueue.pop(0)
        avg = (state["start"]+state["end"])/2
        
        runSim(length, avg, trace, delta_s, sub_material);
        
        if((state["end"] - avg)/2 >= minInterval):
            stateQueue.append({"start":state["start"],"end":avg})
            stateQueue.append({"start":avg,"end":state["end"]})
        
    
    

try:
    # Connect to the mySQL server.
    database.connect()
    
    # Connect to monitoring server
    if ENABLE_MONITOR:
        monitorServer = monitor_client.connect_to_server()
    
    # Run the simulations
    for length in [4.85, 4.6, 4.35, 4.1, 3.6, 3.1, 2.6, 2.1, 1.6, 1.1]:
        runSims(0.5,5.0,length,"top", 0.0005, "Rogers RO3010")
        #runSims(0.5,5.0,length,"mid", 0.0005, "Rogers RO3010")
        #runSims(0.5,5.0,length,"bot", 0.0005, "Rogers RO3010")
    
    # Disconnect from monitoring server
    if ENABLE_MONITOR:
        monitor_client.disconnect(monitorServer)
    
    #disconnect from database
    database.disconnect()
        
except Error as e:
    print("Error Connecting to Database", e)